#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "baseserialport.h"

#include <QSerialPort>     //提供访问串口的功能
#include <QSerialPortInfo> //提供系统中存在的串口的信息
#include <QDebug>

#include <QFileDialog>
#include <QMessageBox>

MainWindow::MainWindow(
    QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->pushButtonOpenPort->setEnabled(false);
    ui->pushButtonClosePort->setEnabled(false);
    ui->pushButtonWriteData->setEnabled(false);
    ui->pushButtonReadData->setEnabled(false);

    connect(this, &MainWindow::open, &serialPort, &BaseSerialport::open);
    connect(this, &MainWindow::send, &serialPort, &BaseSerialport::send);
    connect(this, &MainWindow::receive, &serialPort, &BaseSerialport::receive);
    connect(this, &MainWindow::close, &serialPort, &BaseSerialport::close);

    connect(&serialPort, &BaseSerialport::openResult, this, &MainWindow::serialPortOpenResult);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButtonGetPortList_clicked()
{
    ui->comboBoxPortList->clear();
    /* 清楚下拉框的选项 防止多次点击造成重复 */
    ui->comboBoxPortList->clear();

    foreach (QSerialPortInfo info, QSerialPortInfo::availablePorts())
    {
        ui->comboBoxPortList->addItem(info.portName());

        // ui->comboBoxPortList->addItem(QString(info.portName() + "" + info.description()));
    }

    connect(this, &MainWindow::open, &serialPort, &BaseSerialport::open);
    connect(this, &MainWindow::send, &serialPort, &BaseSerialport::send);
    connect(this, &MainWindow::receive, &serialPort, &BaseSerialport::receive);
    connect(this, &MainWindow::close, &serialPort, &BaseSerialport::close);

    connect(&serialPort, &BaseSerialport::openResult, this, &MainWindow::serialPortOpenResult);
    connect(&serialPort, &BaseSerialport::receiveok, this, &MainWindow::serialPortReceiveOK);

    // 先获取后 再允许打开串口 发送数据 接收数据 关闭串口
    ui->pushButtonOpenPort->setEnabled(true);
    ui->pushButtonWriteData->setEnabled(true);
    ui->pushButtonReadData->setEnabled(true);
    ui->pushButtonClosePort->setEnabled(true);
}

void MainWindow::on_pushButtonOpenPort_clicked()
{
    ui->pushButtonGetPortList->setEnabled(false);
    ui->comboBoxPortList->setEnabled(false);
    ui->comboBoxBourdRate->setEnabled(false);
    ui->comboBoxDataBit->setEnabled(false);
    ui->comboBoxDataParity->setEnabled(false);
    ui->comboBoxStopBits->setEnabled(false);

    QSerialPort::BaudRate baudRate;
    QSerialPort::StopBits stopBits;
    QSerialPort::DataBits dataBits;
    QSerialPort::Parity dataParity;

    // 波特率
    if (ui->comboBoxBourdRate->currentText() == "9600")
    {
        baudRate = QSerialPort::Baud9600;
    }
    else if (ui->comboBoxBourdRate->currentText() == "19200")
    {
        baudRate = QSerialPort::Baud19200;
    }
    else if (ui->comboBoxBourdRate->currentText() == "38400")
    {
        baudRate = QSerialPort::Baud38400;
    }
    else if (ui->comboBoxBourdRate->currentText() == "57600")
    {
        baudRate = QSerialPort::Baud57600;
    }
    else if (ui->comboBoxBourdRate->currentText() == "115200")
    {
        baudRate = QSerialPort::Baud115200;
    }

    // 停止位
    if (ui->comboBoxStopBits->currentText() == "1")
    {
        stopBits = QSerialPort::OneStop;
    }
    else if (ui->comboBoxStopBits->currentText() == "1.5")
    {
        stopBits = QSerialPort::OneAndHalfStop;
    }
    else if (ui->comboBoxStopBits->currentText() == "2")
    {
        stopBits = QSerialPort::TwoStop;
    }

    // 数据位
    if (ui->comboBoxDataBit->currentText() == "5")
    {
        dataBits = QSerialPort::Data5;
    }
    else if (ui->comboBoxDataBit->currentText() == "6")
    {
        dataBits = QSerialPort::Data6;
    }
    else if (ui->comboBoxDataBit->currentText() == "7")
    {
        dataBits = QSerialPort::Data7;
    }
    else if (ui->comboBoxDataBit->currentText() == "8")
    {
        dataBits = QSerialPort::Data8;
    }

    // 校验位
    if (ui->comboBoxDataParity->currentText() == "None")
    {
        dataParity = QSerialPort::NoParity;
    }
    else if (ui->comboBoxDataParity->currentText() == "Odd")
    {
        dataParity = QSerialPort::OddParity;
    }
    else if (ui->comboBoxDataParity->currentText() == "Even")
    {
        dataParity = QSerialPort::EvenParity;
    }

    emit open(ui->comboBoxPortList->currentText(), baudRate, dataBits, dataParity, stopBits);
}

void MainWindow::on_pushButtonClosePort_clicked()
{
    ui->pushButtonGetPortList->setEnabled(true);
    ui->comboBoxPortList->setEnabled(true);
    ui->comboBoxBourdRate->setEnabled(true);
    ui->comboBoxDataBit->setEnabled(true);
    ui->comboBoxDataParity->setEnabled(true);
    ui->comboBoxStopBits->setEnabled(true);
    emit close();
}

void MainWindow::on_pushButtonWriteData_clicked()
{
    QByteArray text = ui->textEdit->toPlainText().toUtf8();
    emit send(text);
}

void MainWindow::serialPortOpenResult(
    bool res)
{
    if (res)
    {
        qDebug() << "open success ";
        ui->pushButtonClosePort->setEnabled(true);
        ui->pushButtonWriteData->setEnabled(true);
        ui->pushButtonReadData->setEnabled(true);
    }
    else
    {
        qDebug() << "open faile ";
        ui->pushButtonGetPortList->setEnabled(true);
        ui->comboBoxPortList->setEnabled(true);
        ui->comboBoxBourdRate->setEnabled(true);
        ui->comboBoxDataBit->setEnabled(true);
        ui->comboBoxDataParity->setEnabled(true);
        ui->comboBoxStopBits->setEnabled(true);
    }
}

void MainWindow::on_pushButtonReadData_clicked()
{
    emit receive();
}

void MainWindow::serialPortReceiveOK(
    QByteArray data)
{
    ui->textBrowser->insertPlainText(data);
}

const static int PACKET_SIZE = 1024; // 每次发送的字节数

void MainWindow::on_toolButtonChooseFile_clicked()
{
    QString path = QFileDialog::
        getOpenFileName(this,
                        tr("Open File"),         // 控件的objectName
                        ".",                     // 对话框显示时默认打开的目录，"." 代表程序运行目录
                        tr("Bin Files(*.bin)")); // 对话框的后缀名过滤器，将txt文件改为bin文件。
    qDebug("path = %s", qPrintable(path));

    if (!path.isEmpty())
    {
        QFile file(path);
        if (!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::warning(this, tr("Read File"), tr("Cannot open file:\n%1").arg(path));
            return;
        }

        file.setFileName(path);
        QFileInfo fileInfo(path);
        auto fileLen = fileInfo.size();                           // 待发送文件大小
        auto sendCnt = (int) ceil(fileLen / (PACKET_SIZE * 1.0)); // 发送次数
        auto lastLen = fileLen % PACKET_SIZE;                     // 最后一次发送的大小

        qDebug() << "fileLen,lastLen,sendCnt:" << fileLen << lastLen << sendCnt;

        if (file.open(QIODevice::ReadOnly))
        {
            QDataStream dataStream(&file);
            char *pBuf = new char[fileLen];
            memset(pBuf, 0, fileLen);
            dataStream.readRawData(pBuf, fileLen);

            qDebug() << QString::asprintf("%02X %02X", (uint8_t) pBuf[0], (uint8_t) pBuf[1]);
            qDebug() << QString::asprintf("%02X %02X", (uint8_t) pBuf[2], (uint8_t) pBuf[3]);
            qDebug() << QString::asprintf("%02X %02X", (uint8_t) pBuf[4], (uint8_t) pBuf[5]);
            qDebug() << QString::asprintf("%02X %02X", (uint8_t) pBuf[6], (uint8_t) pBuf[7]);
            qDebug() << QString::asprintf("%02X %02X", (uint8_t) pBuf[8], (uint8_t) pBuf[9]);
            qDebug() << QString::asprintf("%02X %02X", (uint8_t) pBuf[10], (uint8_t) pBuf[11]);

            qDebug() << QString::asprintf("%02X %02X",
                                          (uint8_t) pBuf[fileInfo.size() - 2],
                                          (uint8_t) pBuf[fileInfo.size() - 1]);
        }

        file.close();
    }
}

